package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CacheType;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.engine.assistant.core.utils.SessionUtil;
import com.bifang.engine.cache.jetcache.utils.JetCacheUtils;
import com.bifang.engine.data.core.util.PagerUtil;
import com.bifang.module.base.common.vo.common.CommonVO;
import com.bifang.module.base.common.vo.dict.DictAreaVO;
import com.bifang.module.base.common.vo.dict.SelectVO;
import com.bifang.module.base.core.helper.DictHelper;
import com.bifang.module.base.core.integration.CommonIntegration;
import com.bifang.module.base.core.integration.DictIntegration;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.constant.EduCache;
import com.jwsoft.manager.common.enums.EduConfigEnum;
import com.jwsoft.manager.common.vo.cache.EduOperationCacheDetailVO;
import com.jwsoft.manager.common.vo.cache.EduOperationCacheQueryVO;
import com.jwsoft.manager.common.vo.cache.EduOperationCacheVO;
import com.jwsoft.manager.common.vo.eduSystemConfig.EduSystemConfigFuncQueryVO;
import com.jwsoft.manager.common.vo.eduSystemConfig.EduSystemConfigKeyVO;
import com.jwsoft.manager.common.vo.eduSystemConfig.EduSystemConfigQueryVO;
import com.jwsoft.manager.common.vo.eduSystemConfig.EduSystemConfigVO;
import com.jwsoft.manager.core.dao.model.EduSystemConfig;
import com.jwsoft.manager.core.dao.service.EduSystemConfigService;
import com.jwsoft.manager.core.integration.EduSystemConfigIntegration;
import com.jwsoft.manager.core.integration.OperationCacheIntegration;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 教育系统配置业务实现类
 *
 * @author dlb
 * @since 2023-02-02
 */
@ApiService(funcCode = "EduSystemConfig", title = "教育系统配置")
public class EduSystemConfigIntegrationImpl implements EduSystemConfigIntegration {

    @Autowired
    public EduSystemConfigService eduSystemConfigService;
    @Autowired
    private OperationCacheIntegration operationCacheIntegration;
    @Autowired
    private DictHelper dictHelper;
    @Autowired
    private DictIntegration dictIntegration;
    @Autowired
    private CommonIntegration commonIntegration;

    @Override
    @OpApi(funcCode = "EduSystemConfig0001", title = "教育系统配置分页查询", funcType = FuncTypeEnum.query)
    public PageInfo<EduSystemConfigVO> getList(EduSystemConfigQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        List<String> areaCodeList = new ArrayList<>();
        if (ObjectUtils.isEmpty(vo.getAreaCode())){
            List<SelectVO> selectVOList = dictIntegration.getDistrictByOrg(new DictAreaVO());
            areaCodeList = selectVOList.stream()
                    .map(SelectVO::getDictKey)
                    .collect(Collectors.toList());
            String sessionAreaCode = SessionUtil.getAreaCode();
            if (!areaCodeList.contains(sessionAreaCode)){
                areaCodeList.add(sessionAreaCode);
            }
        }else {
            areaCodeList.add(vo.getAreaCode());
        }
        if (CollectionUtils.isEmpty(areaCodeList)){
            throw new AppException("必须传入行政区划");
        }
        PageHelper.startPage(vo.getPageNum(),vo.getPageSize());
        LambdaQueryWrapper<EduSystemConfig> eduSystemConfigQueryWrapper = new LambdaQueryWrapper<>();
        eduSystemConfigQueryWrapper
                .in(EduSystemConfig::getAreaCode,areaCodeList)
                .like(!ObjectUtils.isEmpty(vo.getEduConfigKey()),EduSystemConfig::getEduConfigKey,vo.getEduConfigKey())
                .like(!ObjectUtils.isEmpty(vo.getFuncCode()),EduSystemConfig::getFuncCode,vo.getFuncCode())
                .orderByAsc(EduSystemConfig::getFuncCode);
        List<EduSystemConfig> list = eduSystemConfigService.list(eduSystemConfigQueryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduSystemConfig> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduSystemConfigVO> resultList = Convert.toList(EduSystemConfigVO.class, pageInfo.getList());
        // 转义数据字典值
        dictHelper.valueToName(resultList, Arrays.asList(EduConfigEnum.values()));
        return PagerUtil.parsePagerVo(resultList, pageInfo);
    }

    @Override
    @OpApi(funcCode = "EduSystemConfig0002", title = "教育系统配置根据主键查询详情", funcType = FuncTypeEnum.query)
    public EduSystemConfigVO getById(EduSystemConfigKeyVO vo) {
        EduSystemConfig entity = eduSystemConfigService.getById(vo.getSystemCofingId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到详细信息!");
        }
        EduSystemConfigVO result = Convert.convert(EduSystemConfigVO.class, entity);
        return result;
    }
    /** 保存前统一校验*/
    @Override
    @OpApi(funcCode = "EduSystemConfig0003", title = "教育系统配置保存前校验", funcType = FuncTypeEnum.other ,checkPrivilege = BoolEnum.FALSE)
    public void checkSave(EduSystemConfigVO vo) {
        if(ObjectUtils.isEmpty(vo.getSystemCofingId())){
            if(StringUtils.isEmpty(vo.getEduConfigKey())){
                throw new AppException("未选择参数！");
            }
            if(StringUtils.isEmpty(vo.getAreaCode())){
                throw new AppException("未选择统筹区！");
            }
            if(StringUtils.isEmpty(vo.getFuncCode())){
                throw new AppException("未填写功能编号！");
            }
            LambdaQueryWrapper<EduSystemConfig> eduSystemConfigQueryWrapper = new LambdaQueryWrapper<>();
            eduSystemConfigQueryWrapper.eq(EduSystemConfig::getEduConfigKey,vo.getEduConfigKey())
                    .eq(EduSystemConfig::getAreaCode,vo.getAreaCode());
            EduSystemConfig eduSystemConfig = eduSystemConfigService.getOne(eduSystemConfigQueryWrapper);
            if(!ObjectUtils.isEmpty(eduSystemConfig)){
                throw new AppException("有重复数据，请在原数据进行修改");
            }
        }
    }

    @Override
    @OpApi(funcCode = "EduSystemConfig0004", title = "教育系统配置新增", funcType = FuncTypeEnum.insert)
    @SaveOplog(
            operationType = "EduSystemConfig0004",
            operationName = "教育系统配置新增",
            dataType = "systemCofingId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduSystemConfigVO add(EduSystemConfigVO vo) {
        //保存前校验
        checkSave(vo);
        //保存数据
        EduSystemConfig entity = Convert.convert(EduSystemConfig.class, vo);
        dictHelper.valueToName(entity, Arrays.asList(EduConfigEnum.values()));
        entity.setEduConfigName(entity.getEduConfigKeyName());
        eduSystemConfigService.save(entity);
        //将主键设置回vo使操作日志可以取到
        vo.setSystemCofingId(entity.getSystemCofingId());
        return vo;
    }

    @Override
    @OpApi(funcCode = "EduSystemConfig0005", title = "教育系统配置修改", funcType = FuncTypeEnum.update)
    @SaveOplog(
            operationType = "EduSystemConfig0005",
            operationName = "教育系统配置修改",
            dataType = "systemCofingId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduSystemConfigVO edit(EduSystemConfigVO vo) {
        if (ObjectUtils.isEmpty(vo.getSystemCofingId())) {
            throw new AppException("传入需要修改的主键不能为空!");
        }
        EduSystemConfig oldEntity = eduSystemConfigService.getById(vo.getSystemCofingId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要修改的信息!");
        }
        //保存前校验
        checkSave(vo);
        //保存数据
        dictHelper.valueToName(vo, Arrays.asList(EduConfigEnum.values()));
        EduSystemConfig entity = Convert.convert(EduSystemConfig.class, vo);
        entity.setEduConfigName(entity.getEduConfigKeyName());
        eduSystemConfigService.updateById(entity);
        clearCache(entity.getAreaCode(),entity.getEduConfigKey());
        return vo;
    }

    @Override
    @OpApi(funcCode = "EduSystemConfig0006", title = "教育系统配置根据主键删除", funcType = FuncTypeEnum.delete)
    @SaveOplog(
            operationType = "EduSystemConfig0006",
            operationName = "教育系统配置删除",
            dataType = "systemCofingId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void del(EduSystemConfigKeyVO vo) {
        List<Long> ids = vo.getSystemCofingIds();
        List<EduSystemConfig> list = eduSystemConfigService.listByIds(ids);
        if (CollectionUtils.isEmpty(list)) {
            throw new AppException("未找到需要删除的信息!");
        }
        eduSystemConfigService.removeByIds(ids);
        for(EduSystemConfig entity:list){
            clearCache(entity.getAreaCode(),entity.getEduConfigKey());
        }
    }

    @Override
    public EduOperationCacheVO getEduOperation(EduOperationCacheQueryVO vo) {
        vo.setCurTime(new Date());
        if(StringUtils.isBlank(vo.getClassify())){
            throw new AppException("请传入查询的是义务段还是幼儿园");
        }
        if(StringUtils.isBlank(vo.getAreaCode())){
            vo.setAreaCode(SessionUtil.getAreaCode());
        }
        if(StringUtils.isBlank(vo.getAreaCode())){
            CommonVO commonVO=new CommonVO();
            commonVO.setParamKey("area_code");
            String areaCode=commonIntegration.getValueByKey(commonVO);
            vo.setAreaCode(areaCode);
        }
        vo.setKeyTime(vo.getClassify()+":"+vo.getAreaCode()+":"+ DateUtil.format(new Date(),"yyyyMMdd"));
        EduOperationCacheVO eduOperationCacheVO= operationCacheIntegration.getEduOperation(vo);
        if(!CollectionUtils.isEmpty(eduOperationCacheVO.getOperation())){
            for(EduOperationCacheDetailVO operationPeriod:eduOperationCacheVO.getOperation().values()){
                if(StringUtils.isBlank(operationPeriod.getType())){
                    Long  begTime =null;
                    Long  endTime =null;
                    Long  curTime = vo.getCurTime().getTime()/1000;
                    if(operationPeriod.getBegTime()!=null){
                        begTime = operationPeriod.getBegTime().getTime()/1000;
                    }
                    if(operationPeriod.getEndTime()!=null){
                        endTime = operationPeriod.getEndTime().getTime()/1000;
                    }
                    if(begTime!=null&&curTime<begTime){
                        operationPeriod.setFlag(false);
                        operationPeriod.setType("1");
                        if(StringUtils.isBlank(operationPeriod.getMessagePrompts())){
                            operationPeriod.setMessagePrompts(eduOperationCacheVO.getYear()+"年度招生工作尚未开始！");
                        }
                        continue;
                    }else if(endTime!=null&&curTime>endTime){
                        operationPeriod.setFlag(false);
                        operationPeriod.setType("2");
                        if(StringUtils.isBlank(operationPeriod.getMessageTip())){
                            operationPeriod.setMessageTip(eduOperationCacheVO.getYear()+"年度招生工作已结束！");
                        }
                        continue;
                    }else{
                        if(begTime==null||endTime==null){
                            operationPeriod.setFlag(false);
                        }else {
                            operationPeriod.setFlag(true);
                        }
                    }
                }
            }
        }

        return eduOperationCacheVO;
    }




    @Override
    @OpApi(funcCode = "OperationCache0003", title = "根据业务期类型获取单个招生时间控制参数 ", funcType = FuncTypeEnum.query,publicFlag = BoolEnum.TRUE,savelog = false)
    public EduOperationCacheDetailVO getEduOperationOne(EduOperationCacheQueryVO vo) {
        if(StringUtils.isBlank(vo.getOperating())){
            throw new AppException("请传入业务期控制类型");
        }
        EduOperationCacheVO eduOperationCacheVO=this.getEduOperation(vo);
        return eduOperationCacheVO.getOperation()==null?null:eduOperationCacheVO.getOperation().get(vo.getOperating());
    }

    @Override
    public void checkOperation(EduOperationCacheVO eduOperationCacheVO, String operation) {
        if(StringUtils.isBlank(operation)){
            throw new AppException("请传入业务期控制类型");
        }
        //判断是否在经办业务期内
        Map<String, EduOperationCacheDetailVO> operationMap=eduOperationCacheVO.getOperation();
        EduOperationCacheDetailVO operationCacheDetailVO=operationMap.get(operation);
        if(ObjectUtils.isEmpty(operationCacheDetailVO)){
            throw new AppException("系统获取招生时间失败，退出页面重试");
        }
        if(!operationCacheDetailVO.isFlag()){
            if("1".equalsIgnoreCase(operationCacheDetailVO.getType())){
                if(StringUtils.isBlank(operationCacheDetailVO.getMessagePrompts())){
                    throw new AppException(eduOperationCacheVO.getYear()+"年度招生工作尚未开始！");
                }
                throw new AppException(operationCacheDetailVO.getMessagePrompts());

            }else if("2".equalsIgnoreCase(operationCacheDetailVO.getType())){
                if(StringUtils.isBlank(operationCacheDetailVO.getMessageTip())){
                    throw new AppException(eduOperationCacheVO.getYear()+"年度招生工作已结束！");
                }
                throw new AppException(operationCacheDetailVO.getMessageTip());
            }else if("3".equalsIgnoreCase(operationCacheDetailVO.getType())){
                throw new AppException(eduOperationCacheVO.getYear()+"年度招生工作尚未开始");
            }
        }

    }

    @Override
    @OpApi(funcCode = "OperationCache0004", title = "教育相关业务期单个校验 ", funcType = FuncTypeEnum.query,publicFlag = BoolEnum.TRUE,savelog = false)
    public void checkOperation(EduOperationCacheQueryVO vo) {
        EduOperationCacheVO eduOperationCacheVO=this.getEduOperation(vo);
        checkOperation(eduOperationCacheVO,vo.getOperating());
    }

    @Override
    public String getFuncCode(EduSystemConfigFuncQueryVO vo) {
        if (StringUtils.isBlank(vo.getAreaCode())) {
            throw new AppException("行政区划不能为空");
        }
        if (StringUtils.isBlank(vo.getEduConfigKey())) {
            throw new AppException("参数标识不能为空");
        }
        String key=vo.getAreaCode()+":"+vo.getEduConfigKey();
        Cache cache = JetCacheUtils.create(EduCache.EDU_SYSTEM_CONFIG_FUNC, CacheType.BOTH, Duration.ofSeconds(86400), Duration.ofSeconds(20));
        String value= (String) cache.get(key);
        if(value!=null){
            return value;
        }
        LambdaQueryWrapper<EduSystemConfig> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.select(EduSystemConfig::getFuncCode).eq(EduSystemConfig::getAreaCode,vo.getAreaCode())
                .eq(EduSystemConfig::getEduConfigKey,vo.getEduConfigKey());
        List<EduSystemConfig> list=eduSystemConfigService.list(queryWrapper);
        if(CollectionUtils.isEmpty(list)){
            cache.put(key,"");
            return "";
        }
        cache.put(key,list.get(0).getFuncCode());
        return list.get(0).getFuncCode();
    }

    @Override
    public void clearCache(String areaCode, String eduConfigKey) {
        if (StringUtils.isNotBlank(areaCode)&&StringUtils.isNotBlank(eduConfigKey)) {
            Cache cache = JetCacheUtils.create(EduCache.EDU_SYSTEM_CONFIG_FUNC, CacheType.BOTH);
            if (cache != null) {
                cache.remove(areaCode+":"+eduConfigKey);
            }
        }
    }

}
